package game.cellmap;

import game.AbstractGame;
import game.GameListener;
import game.GraphicUtil;
import game.IImageRenderer;
import game.Position;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;

public abstract class AbstractCellMapGame<TYPE extends CellMap> extends AbstractGame implements IImageRenderer
{
    private TYPE map;
    private int  mouseOverIndex = -1;
    
    protected AbstractCellMapGame(boolean enableScrolling, TYPE map)
    {
        super(enableScrolling);
        this.map = map;
        GameListener.getInstance().addMouseMotionListener(new MouseMotionAdapter() {
            
            @Override
            public void mouseMoved(MouseEvent e)
            {
                if (isRunning())
                {
                    try
                    {
                        mouseOverIndex = getMap().calculateIndex(getMap().calcCoord(calcMousePoint(e.getPoint())));
                    }
                    catch (IndexOutOfBoundsException ex)
                    {
                        //
                    }
                }
            }
            
            @Override
            public void mouseDragged(MouseEvent e)
            {
                if (isRunning())
                {
                    try
                    {
                        mouseOverIndex = getMap().calculateIndex(getMap().calcCoord(calcMousePoint(e.getPoint())));
                    }
                    catch (IndexOutOfBoundsException ex)
                    {
                        //
                    }
                }
            }
        });
    }
    
    protected TYPE getMap()
    {
        return map;
    }
    
    public int getMouseOverIndex()
    {
        return mouseOverIndex;
    }
    
    protected Position getStartXY()
    {
        int startX = 0;
        int startY = 0;
        Position mapSize = getMap().getCellMapSize();
        if (mapSize.getWidth() < getFrameSize().getWidth())
        {
            startX = (int) ((getFrameSize().getWidth() - mapSize.getWidth()) / 2);
        }
        if (mapSize.getHeight() < getFrameSize().getHeight())
        {
            startY = (int) ((getFrameSize().getHeight() - mapSize.getHeight()) / 2);
        }
        return new Position(startX, startY);
    }
    
    protected Position calcMousePoint(Point point)
    {
        Position startXY = getStartXY();
        int x = point.x - startXY.getX();
        int y = point.y - startXY.getY();
        return new Position(x, y);
    }
    
    protected void drawCenteredImage(Graphics g, Image image)
    {
        Position mapSize = getMap().getCellMapSize();
        int endX = mapSize.getWidth();
        int endY = mapSize.getHeight();
        if (endX < getFrameSize().getWidth())
        {
            endX = getFrameSize().width;
        }
        if (endY < getFrameSize().height)
        {
            endY = getFrameSize().height;
        }
        GraphicUtil.fillRect(g, 0, 0, endX, endY, Color.BLACK);
        Position startXY = getStartXY();
        // Logger.log("STARTXY: " + startXY);
        g.drawImage(image, startXY.getX(), startXY.getY(), null);
    }
    
    @Override
    public BufferedImage getImage()
    {
        return null;
    }
    
    @Override
    public void render(Graphics g)
    {
        if (isRunning())
        {
            BufferedImage image = getImage();
            if (image != null)
            {
                drawCenteredImage(g, getImage());
            }
        }
    }
}
